package com.kye.express.business.limit_time_query;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxTextView;
import com.kye.addrpicker.AddressPickerActivity;
import com.kye.addrpicker.model.AddressPickerResult;
import com.kye.addrpicker.utils.StringUtils;
import com.kye.base.DebounceObservableTransformer;
import com.kye.base.utils.DateUtils;
import com.kye.datetimepicker.DateTimePicker;
import com.kye.express.R;
import com.kye.express.business.base.BaseToolbarActivity;
import com.kye.express.databinding.ActivityLimitTimeQueryBinding;
import com.kye.express.view.ToastManager;
import com.kye.model.bean.limit_time_query.ResultFindServiceAging;
import com.tbruyelle.rxpermissions2.Permission;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.util.Date;

import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function3;
import me.drakeet.multitype.Items;
import me.drakeet.multitype.MultiTypeAdapter;

/**
 * 时效查询
 */
public class LimitTimeQueryActivity extends BaseToolbarActivity implements LimitTimeQueryActivityContract.LimitTimeQueryView {

    private static final int REQUEST_CODE_START = 1;
    private static final int REQUEST_CODE_END = 2;

    private ActivityLimitTimeQueryBinding mBinding;
    private Context mContext;

    protected MultiTypeAdapter mAdapter;
    protected Items mDatas = new Items();

    private AddressPickerResult mStartAddress;
    private AddressPickerResult mEndAddress;

    private LimitTimeQueryActivityContract.LimitTimeQueryViewPresenter mPresenter;

    public LocationClient mLocationClient = null;
    private BDAbstractLocationListener mBdAbstractLocationListener;

    public static void startActivity(Context context) {
        Intent intent = new Intent(context, LimitTimeQueryActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_limit_time_query);
        mContext = this;
        mPresenter = new LimitTimeQueryActivityContract.LimitTimeQueryViewPresenter(mContext);
        mPresenter.bind(this);
        setUpToolbar((Toolbar) findViewById(R.id.toolbar));
        setTitle(getString(R.string.limittime_query));
        initView();
        initEvent();
        initLocation();
    }

    @Override
    protected void onDestroy() {
        mPresenter.unbind();
        if (mBdAbstractLocationListener != null) {
            mLocationClient.unRegisterLocationListener(mBdAbstractLocationListener);
        }
        super.onDestroy();
    }

    private void initView() {
        mAdapter = new MultiTypeAdapter();
        mAdapter.register(ResultFindServiceAging.DatasBean.class, new LimitTimeQueryItemViewBinder(mContext));
        mBinding.recyclerview.setLayoutManager(new LinearLayoutManager(mContext));
        mBinding.recyclerview.setItemAnimator(new DefaultItemAnimator());
        mAdapter.setItems(mDatas);
        mBinding.recyclerview.setAdapter(mAdapter);
        mBinding.edtTime.setText(DateUtils.getDateStringByDate(new Date()));
    }

    private void initEvent() {

        Observable<CharSequence> startAddressChange = RxTextView.textChanges(mBinding.edtStartAddress).cache();
        Observable<CharSequence> endAddressChange = RxTextView.textChanges(mBinding.edtEndAddress).cache();
        Observable<CharSequence> timeChange = RxTextView.textChanges(mBinding.edtTime).cache();

        Observable.combineLatest(startAddressChange, endAddressChange, timeChange, new Function3<CharSequence, CharSequence, CharSequence, Boolean>() {
            @Override
            public Boolean apply(CharSequence charSequence, CharSequence charSequence2, CharSequence charSequence3) throws Exception {
                return !TextUtils.isEmpty(charSequence) && !TextUtils.isEmpty(charSequence2) && !TextUtils.isEmpty(charSequence3);
            }
        }).compose(this.<Boolean>bindToLifecycleDestroy())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        mBinding.btnQuery.setEnabled(aBoolean);
                    }
                });

        RxView.clicks(mBinding.edtStartAddress)
                .compose(new DebounceObservableTransformer<>())
                .compose(this.bindToLifecycleDestroy())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        AddressPickerActivity.startActivityForResult(LimitTimeQueryActivity.this, getString(R.string.limittime_start_address), AddressPickerActivity.Levels.area, REQUEST_CODE_START);
                    }
                });

        RxView.clicks(mBinding.edtEndAddress)
                .compose(new DebounceObservableTransformer<>())
                .compose(this.bindToLifecycleDestroy())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        AddressPickerActivity.startActivityForResult(LimitTimeQueryActivity.this, getString(R.string.limittime_end_address), AddressPickerActivity.Levels.area, REQUEST_CODE_END);
                    }
                });

        RxView.clicks(mBinding.edtTime)
                .compose(new DebounceObservableTransformer<>())
                .compose(this.bindToLifecycleDestroy())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        DateTimePicker.show(mContext, true, true, true, true, true, false, new DateTimePicker.DateTimeCallBack() {
                            @Override
                            public void callBack(Date date) {
                                if (date != null) {
                                    mBinding.edtTime.setText(DateUtils.getDateStringByDate(date));
                                }
                            }
                        });
                    }
                });

        RxView.clicks(mBinding.btnQuery)
                .compose(new DebounceObservableTransformer<>())
                .compose(this.bindToLifecycleDestroy())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        if (mStartAddress != null && mEndAddress != null) {
                            mPresenter.loadDatas(mStartAddress, mEndAddress, mBinding.edtTime.getText().toString());
                            mBinding.tvQueryResult.setVisibility(View.GONE);
                            mDatas.clear();
                            mAdapter.notifyDataSetChanged();
                        }
                    }
                });

        RxView.clicks(mBinding.ivLocation)
                .compose(new DebounceObservableTransformer<>())
                .compose(this.bindToLifecycleDestroy())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        RxPermissions rxPermissions = new RxPermissions(LimitTimeQueryActivity.this);
                        rxPermissions.requestEach(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION)
                                .subscribe(new Consumer<Permission>() {
                                    @Override
                                    public void accept(Permission permission) throws Exception {
                                        if (permission.granted) {
                                            if (mLocationClient != null) {
                                                mLocationClient.start();
                                            }
                                        } else {
                                            ToastManager.show(mContext, R.string.limit_time_no_getlocation_permission);
                                        }
                                    }
                                });
                    }
                });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK && data != null) {
            AddressPickerResult resultAddress = (AddressPickerResult) data.getSerializableExtra(AddressPickerActivity.KEY_ARG_PICKED_RESULT);
            if (resultAddress != null) {
                if (requestCode == REQUEST_CODE_START) {
                    mStartAddress = resultAddress;
                    mBinding.edtStartAddress.setText(resultAddress.getProvince() + resultAddress.getCity() + resultAddress.getArea() + resultAddress.getStreet());
                } else if (requestCode == REQUEST_CODE_END) {
                    mEndAddress = resultAddress;
                    mBinding.edtEndAddress.setText(resultAddress.getProvince() + resultAddress.getCity() + resultAddress.getArea() + resultAddress.getStreet());
                }
            }
        }

    }

    @Override
    public void onComplete() {
        mBinding.statusLayout.showContentView();
    }

    @Override
    public void onLoading() {
        mBinding.statusLayout.showLoadingView();
    }

    @Override
    public void onLoaded(ResultFindServiceAging datas) {
        mBinding.statusLayout.showContentView();
        if (datas != null && datas.getDatas() != null && datas.getDatas().size() > 0) {
            mBinding.tvQueryResult.setVisibility(View.VISIBLE);
            mDatas.clear();
            addTitleData();
            mDatas.addAll(datas.getDatas());
            addBottomData();
            mAdapter.notifyDataSetChanged();
        } else {
            mBinding.tvQueryResult.setVisibility(View.GONE);
            ToastManager.show(mContext, R.string.common_no_datas, Toast.LENGTH_SHORT);
        }
    }

    @Override
    public void onError(String msg) {
        ToastManager.show(this, msg, Toast.LENGTH_SHORT);
    }

    private void addTitleData() {
        ResultFindServiceAging.DatasBean datasBean = new ResultFindServiceAging.DatasBean();
        datasBean.setServiceMode(getString(R.string.limittime_service_type));
        datasBean.setSendAging(getString(R.string.limittime_estimate_time));
        datasBean.setTitle(true);
        mDatas.add(0, datasBean);
    }

    private void addBottomData() {
        ResultFindServiceAging.DatasBean datasBean = new ResultFindServiceAging.DatasBean();
        datasBean.setServiceMode("");
        datasBean.setSendAging(getString(R.string.limittime_appendix));
        datasBean.setBottom(true);
        mDatas.add(datasBean);
    }

    private void initLocation() {
        mLocationClient = new LocationClient(getApplicationContext());
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        option.setCoorType("bd09ll");
        option.setScanSpan(0);
        option.setIsNeedAddress(true);
        option.setOpenGps(true);
        option.setLocationNotify(true);
        option.setIgnoreKillProcess(false);
        option.SetIgnoreCacheException(false);
        option.setWifiCacheTimeOut(5 * 60 * 1000);
        option.setEnableSimulateGps(false);
        mLocationClient.setLocOption(option);
        mBdAbstractLocationListener = new BDAbstractLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation bdLocation) {
                if (bdLocation != null) {
                    String province = bdLocation.getProvince();
                    String city = bdLocation.getCity();
                    String district = bdLocation.getDistrict();
                    String street = bdLocation.getStreet();
                    if (!TextUtils.isEmpty(city) && (!TextUtils.isEmpty(district))) {
                        String location = StringUtils.extractLocation(city, district);
                        mBinding.edtStartAddress.setText(province+location);
                        mStartAddress = new AddressPickerResult(province,city,district,"");
                    } else {
                        ToastManager.show(mContext, R.string.limit_time_getlocation_failed);
                    }
                } else {
                    ToastManager.show(mContext, R.string.limit_time_getlocation_failed);
                }
            }
        };
        mLocationClient.registerLocationListener(mBdAbstractLocationListener);
    }
}
